﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

/// <summary>
/// Summary description for VideoProcess
/// </summary>
public class VideoProcess
{
    //FFmpeg配置信息
    private static string ffmpegpath = "/ffmpeg/ffmpeg.exe";//FFmpeg的服务器路径

    public static string FFmpegpath
    {
        get
        {
            if (!File.Exists(HttpContext.Current.Server.MapPath(ffmpegpath)))
            {
                throw new FileNotFoundException("FFmpeg文件未找到");
            }
            return HttpContext.Current.Server.MapPath(VideoProcess.ffmpegpath);
        }
    }
    public VideoProcess()
    {
        //
        // TODO: Add constructor logic here
        //
    }


    /// <summary>
    /// FFmpeg取视频截图
    /// </summary>
    /// <param name="videoPath"></param>
    /// <param name="coverWidth"></param>
    /// <param name="coverHeight"></param>
    /// <param name="startPoint"></param>
    /// <param name="coverSavePath"></param>
    public static string GetVideoCover(string videoPath, int coverWidth, int coverHeight, int startPoint, string savePath)
    {
        System.Diagnostics.ProcessStartInfo ImgstartInfo = new System.Diagnostics.ProcessStartInfo(FFmpegpath);

        // we want to execute the process without opening a shell
        ImgstartInfo.UseShellExecute = false;
        ImgstartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        /*参数设置
         * -y（覆盖输出文件，即如果生成的文件（flv_img）已经存在的话，不经提示就覆盖掉了）
         * -i 1.avi 输入文件
         * -f image2 指定输出格式
         * -ss 8 后跟的单位为秒，从指定时间点开始转换任务
         * -vframes
         * -s 指定分辨率
         */
        ImgstartInfo.Arguments = string.Format(" -i {0} -y -f image2 -ss {1} -vframes 1 -s {2}*{3} {4}", videoPath, startPoint, coverWidth, coverHeight, savePath);
        try
        {
            System.Diagnostics.Process.Start(ImgstartInfo);
            return savePath;
        }
        catch (Exception e)
        {
            throw new Exception("截图进程执行出错！", e);
        }
    }

    /// <summary>
    /// 获取视频长度
    /// </summary>
    /// <param name="videoPath"></param>
    /// <returns></returns>
    public static string GetVideoLength(string videoPath)
    {
        //取得ffmpeg.exe的物理路径
        using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process())
        {
            String duration;  // soon will hold our video's duration in the form "HH:MM:SS.UU"
            String result;  // temp variable holding a string representation of our video's duration
            StreamReader errorreader;  // StringWriter to hold output from ffmpeg

            // we want to execute the process without opening a shell
            ffmpeg.StartInfo.UseShellExecute = false;
            //ffmpeg.StartInfo.ErrorDialog = false;
            ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            // redirect StandardError so we can parse it
            // for some reason the output comes through over StandardError
            ffmpeg.StartInfo.RedirectStandardError = true;

            // set the file name of our process, including the full path
            // (as well as quotes, as if you were calling it from the command-line)
            ffmpeg.StartInfo.FileName = FFmpegpath;

            // set the command-line arguments of our process, including full paths of any files
            // (as well as quotes, as if you were passing these arguments on the command-line)
            ffmpeg.StartInfo.Arguments = "-i " + videoPath;

            // start the process
            ffmpeg.Start();

            // now that the process is started, we can redirect output to the StreamReader we defined
            errorreader = ffmpeg.StandardError;

            // wait until ffmpeg comes back
            ffmpeg.WaitForExit();

            // read the output from ffmpeg, which for some reason is found in Process.StandardError
            result = errorreader.ReadToEnd();

            // a little convoluded, this string manipulation...
            // working from the inside out, it:
            // takes a substring of result, starting from the end of the "Duration: " label contained within,
            // (execute "ffmpeg.exe -i somevideofile" on the command-line to verify for yourself that it is there)
            // and going the full length of the timestamp

            duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);

            //string[] time = VideoLength.Split(':');
            //int seconds = int.Parse(time[0]) * 60 * 60 + int.Parse(time[1]) * 60 + int.Parse(time[2]);
            return duration;
        }
    }
}